<?php

namespace app\common\model\merchant;


use app\common\model\BaseModel;
use think\db\exception\DbException;
use think\Exception;


/**
 * 商户商品表
 * Class Product
 * @package app\common\model
 */
class ProductModel extends BaseModel
{
    //
    protected $name = 'product';

    // 设置字段信息
    protected $schema = [
        'id' => 'int',        // 分类ID
        'mer_id' => 'string',        // 商户ID
        'code' => 'string',        //
        'title' => 'string',        // 商品名称
        'sub_title' => 'string',        // 商品名称
        'class_id' => 'int',        // 所属分类
        'pics' => 'string',        // 商品主图
        'images' => 'string',        // 详情图
        'describe' => 'string',        // 描述
        'op_user' => 'int',        // 操作人
        'create_at' => 'datetime',        // 创建时间
        'update_at' => 'datetime',        // 更新时间
        'delete_at' => 'datetime',        // 删除时间 不为null, 已删除
    ];


    /**
     * 分页列表
     * @param array $where
     * @param       $page
     * @param       $cont
     * @return mixed
     * @throws DbException
     */
    public function proPage(array $where, $page = '1', $cont = 30)
    {

        return $this->db()->alias('pro')
            ->join('product_class c', 'pro.class_id=c.id')
            ->where($where ?? [])
            ->whereNull('delete_at')
            ->field('pro.id,pro.warn_num,pro.code,pro.mer_id,pro.title,pro.sub_title,c.title as class_title,pro.class_id,pro.update_at')
            ->order('pro.id desc')
            ->paginate(['page' => $page, 'list_rows' => $cont]);
    }

    /**
     * 修改、添加
     * @param     $data
     * @param int $id
     * @return bool
     * @throws DbException|\Exception
     */
    public function proSave($data, int $id = 0): bool
    {

        if ($id !== 0) {
            $where[] = ['id', '<>', $id];
        }
        if (isset($data['id'])) {
            unset($data['id']);
        }
        //重复
        $cont = $this->db()->where($where ?? [])
            ->whereNull('delete_at')
            ->where('mer_id', $data['mer_id'])->whereRaw('code=:code or title=:title', ['code' => $data['code'], 'title' => $data['title']])
            ->count('id');
        if ($cont > 0) {
            throw new Exception('已有该商品或（货号）');
        }

        $data['update_at'] = date('Y-m-d H:i:s');
        if ($id !== 0) {
            // 商品code
            $product_code  = $this->db()->where('id',$id)->value('code');
            try {
                $this->db()->startTrans();
                if ((string)$product_code !== (string)$data['code']){
                    $whereCode  = ['mer_id' => $data['mer_id'],'product_code' => $product_code];
                    $updateCode = ['product_code' => $data['code']];
                    $out_num = $this->db('shop_stock')->where($whereCode)->sum('out_num');
                    if ($out_num >= 1){
                        throw new Exception('商品编码已经使用无法修改', API_ERROR);
                    }
                    $this->db('shop_stock')->removeOption()->where($whereCode)->update($updateCode);
                    $this->db('virtual_promo_product')->removeOption()->where($whereCode)->update($updateCode);
                    $this->db('order_detail')->removeOption()->where($whereCode)->update($updateCode);
                }else {
                    unset($data['code']);
                }
                $data = $this->db()->removeOption()->where('id', $id)->where('mer_id', $data['mer_id'])->update($data);
                $this->db()->commit();
                return  $data;
            }catch (Exception $e){
                $this->db()->rollback();
                throw  $e;
            }
        }
        $id = $this->db()->insert($data, true);
        if ($id) {
            $img = array_merge(explode(',', $data['pics']), explode(',', $data['images']));
            updateUploadStatus($img, $id);
        }
        return true;

    }

    //同步商品CODE
    private function syncProductCode($id, string $newCode): void
    {
        $oldInfo = $this->db()->where('id', $id)->field('mer_id,code')->find();
        // 商品Code不相符
        if (!empty($oldInfo) && $oldInfo['code'] !== $newCode) {
            $map = ['mer_id' => $id, 'product_code' => $oldInfo['code']];

            //$map = ['mer_id' => $id];
        }
    }

    /**
     * 详情
     * @param $id
     * @throws  \Exception
     */
    public function proInfo($id)
    {
        $data = $this->db()->alias('g')->join('product_class c', 'g.class_id=c.id')
            ->where('g.id', $id)->where('delete_at', null)
            ->field('g.id,g.code,g.title,g.sub_title,g.pics,g.images,g.mer_id,g.op_user,g.warn_num,
            c.title as class_title,c.id as class_id')
            ->find();
        if (!$data) {
            throw new Exception('未找商品', API_ERROR);
        }
        $data['images'] = explode(',', $data['images']);
        return $data;
    }

    /**
     * 列表
     * @param $where |条件
     * @param $list_num |数量
     * @return mixed
     * @throws DbException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function list($where, $list_num, $field)
    {
        return $this->db()->where($where ?? [])->order('create_at desc,id desc')
            ->field($field)->whereNull('delete_at')->limit($list_num)->select();
    }

    /**
     * 根据商户ID 和商品code ,获取对应的商品名称
     * @param string $mer_id 商户ID
     * @param array $product_codes 商户编号
     * @return mixed
     */
    public function getProductTitle(string $mer_id, array $product_codes = [])
    {
        return $this->db()->where('mer_id', $mer_id)->where('code', 'in', $product_codes)
            ->whereNull('delete_at')
            ->cache(true, MINUTES_SECOND_5)
            ->column('title', 'code');
    }

    /**
     * 获取指定商品的名称和分类名称
     * @param string $mer_id
     * @param array $product_codes
     * @return array
     */
    public function getProductAndClassTitle(string $mer_id, array $product_codes)
    {
        return $this->db()->alias('a')->join('product_class b', 'class_id=b.id', 'left')
            ->where('a.mer_id', $mer_id)
            ->where('code', 'in', $product_codes)
            ->whereNull('a.delete_at')
            ->column('code,a.title,sub_title,b.title as class_title', 'code');
    }
}
